﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.Xml;

namespace LocalizationEditor
{
    public partial class MainWindow : Form
    {
        Hashtable stringTable = null;
        bool saved = true;
        string editedFile = "";

        public MainWindow()
        {
            InitializeComponent();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LocalizationList.Clear();
            this.Text = "Localization Editor - New translation";
            keyBox.Items.Clear();
            keyBox.Items.AddRange(GetTranslationKeysList());
            editedFile = "";
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            stringTable = new Hashtable();
            keyBox.Items.AddRange(GetTranslationKeysList());
            keyBox.SelectedIndex = 0;
        }

        private void prevButton_Click(object sender, EventArgs e)
        {
            LocalListPrevItem();
        }    

        private void nextButton_Click(object sender, EventArgs e)
        {
            LocalListNextItem();    
        }

        private void newItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewItemList();
        }

        private void LocalizationList_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                //keyBox.SelectedItem = LocalizationList.Items[LocalizationList.SelectedIndices[0]].Text;
                keyBox.Text = LocalizationList.Items[LocalizationList.SelectedIndices[0]].Text;
                editBox.Text = LocalizationList.Items[LocalizationList.SelectedIndices[0]].SubItems[1].Text;
                keyBox.Enabled = false;
            }
            catch (System.ArgumentOutOfRangeException exc)
            {
                NewItemList();
            }
        }

        private void LocalizationList_MouseUp(object sender, MouseEventArgs e)
        {
            if (LocalizationList.SelectedIndices.Count > 0)
            {
                editBox.Focus();
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DeleteItemFromList();
        }

        private void editBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control == true && e.KeyCode == Keys.Enter)
            {
                try
                {
                    LocalizationList.Items[LocalizationList.SelectedIndices[0]].SubItems[1].Text = editBox.Text;
                    stringTable[LocalizationList.Items[LocalizationList.SelectedIndices[0]].Text] = LocalizationList.Items[LocalizationList.SelectedIndices[0]].SubItems[1].Text;
                    saved = false;
                    e.SuppressKeyPress = true;
                }
                catch (System.Exception exc)
                {

                }
            } else if (e.Control == true && e.KeyCode == Keys.Insert)
            {
                try
                {
                    if (keyBox.Items.Contains(keyBox.Text) == true)
                    {
                        keyBox.SelectedIndex = keyBox.Items.IndexOf(keyBox.Text);
                    }
                    int idx = keyBox.SelectedIndex;
                    if (idx == -1 || keyBox.Text == "")
                    {
                        MessageBox.Show("Key value is not selected");
                        return;
                    }
                    LocalizationList.Items.Add(keyBox.SelectedItem.ToString()).SubItems.Add(editBox.Text);
                    stringTable.Add(keyBox.SelectedItem.ToString(), editBox.Text);
                    keyBox.Items.RemoveAt(keyBox.SelectedIndex);    
                    if (keyBox.Items.Count > 0)
                    {
                        keyBox.SelectedIndex = idx;
                    }
                    else
                    {
                        keyBox.Text = "";
                        keyBox.Enabled = false;
                    }

                    editBox.Text = "";
                    saved = false;
                }
                catch (System.Exception ecx)
                {

                }
            } else if (e.Control == true && e.KeyCode == Keys.Delete)
            {
                DeleteItemFromList();
                saved = false;

            } else if (e.Control == true && e.KeyCode == Keys.Up)
            {
                LocalListPrevItem();
            } else if (e.Control == true && e.KeyCode == Keys.Down)
            {
                LocalListNextItem();
            } else if (e.Control == true && e.KeyCode == Keys.N)
            {
                NewItemList();
                saved = false;
            } 
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            try{
                ExitRoutine();
            }catch(System.Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
            
        }

        private void keyBox_TextUpdate(object sender, EventArgs e)
        {
            int Pos = keyBox.SelectionStart;
            keyBox.Text = keyBox.Text.ToUpper();
            keyBox.SelectionStart = Pos;
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (saved == false)
            {
                if (editedFile == "")
                {
                    SaveAsLangTo();
                    return;

                }
                else
                {
                    SaveLangTo(editedFile);
                    return;
                }
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveAsLangTo();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ExitRoutine();

            keyBox.Items.Clear();
            keyBox.Items.AddRange(GetTranslationKeysList());
            editBox.Text = "";
            LocalizationList.Items.Clear();
            stringTable.Clear();

            List<Entry> list;
     
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                editedFile = openFileDialog.FileName;
                bool missingKeys = false;

                try
                {
                    XmlReaderSettings readerSettings = new XmlReaderSettings();
                    XmlReader reader = XmlReader.Create(editedFile, readerSettings);
                    XmlSerializer serializer = new XmlSerializer(typeof(List<Entry>));
                    list = serializer.Deserialize(reader) as List<Entry>;
                    reader.Close();
                }
                catch (System.Exception exc)
                {
                    MessageBox.Show("File cannot be opened");
                    return;
                }

                foreach (Entry item in list)
                {
                    LocalizationList.Items.Add(item.Key.ToString()).SubItems.Add(item.Value.ToString());
                    stringTable.Add(item.Key.ToString(), item.Value.ToString());
                    
                    int idx = 0;
                    if ((idx = keyBox.Items.IndexOf(item.Key.ToString())) != -1)
                    {
                        keyBox.Items.RemoveAt(idx); 
                    } else {
                        missingKeys = true;
                    }
                    
                }

                if (missingKeys)
                {
                    MessageBox.Show("Some keys in opened file is missing in translation.keys.Maybe old version of translation.keys.");
                }
               
            }

            saved = true;
            if (keyBox.Items.Count > 0)
            {
                keyBox.SelectedIndex = 0;
            } else {
                keyBox.Enabled = false;
            } 
            this.Text = "Localization editor - " + editedFile;
        }

        private string[] GetTranslationKeysList()
        {
            try
            {
	            FileStream fs = new FileStream("Translation.keys", FileMode.Open);
	            StreamReader sr = new StreamReader(fs);
	            string fileText = sr.ReadToEnd();
	            sr.Close();
	            fs.Close();
                return Regex.Split(fileText, "\r\n");
            }
            catch (System.IO.FileNotFoundException e)
            {
                MessageBox.Show("Translation.keys file not found.");
                return null;
            }
        }

        private bool SaveLangTo(string path)
        {
            try
            {
	            XmlWriterSettings writerSettings = new XmlWriterSettings();
	            writerSettings.Encoding = Encoding.UTF8;
	            XmlWriter writer = XmlWriter.Create(path, writerSettings);
	            List<Entry> entries = new List<Entry>(stringTable.Count);
	            foreach (object key in stringTable.Keys)
	            {
	                entries.Add(new Entry(key, stringTable[key]));
	            }   
	            XmlSerializer serializer = new XmlSerializer(typeof(List<Entry>));
	            serializer.Serialize(writer, entries);
	            writer.Flush();
	            writer.Close();
                saved = true;

                return true;
            }
            catch (System.Exception e)
            {
                MessageBox.Show("Language file cannont be saved");
                return false;
            }
        }

        private void SaveAsLangTo()
        {
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                editedFile = saveFileDialog.FileName;
                if (SaveLangTo(editedFile) == false)
                    return;
            }
        }

        private void DeleteItemFromList()
        {
            if (LocalizationList.SelectedIndices.Count > 0)
            {
                stringTable.Remove(LocalizationList.Items[LocalizationList.SelectedIndices[0]].Text);
                keyBox.Items.Add(LocalizationList.SelectedItems[0].Text);
                keyBox.Text = "";
                LocalizationList.Items.RemoveAt(LocalizationList.SelectedIndices[0]);
                editBox.Text = "";
                keyBox.Enabled = true;
            } 
        }

        private void NewItemList()
        {
            editBox.Text = "";
            keyBox.Text = "";
            keyBox.Enabled = true;
            editBox.Focus();
            LocalizationList.SelectedIndices.Clear();
        }

        private void LocalListNextItem()
        {
            int idx = -1;
            try
            {
                idx = LocalizationList.SelectedIndices[0];
            }
            catch (System.Exception exc)
            {
            }
            try
            {
                LocalizationList.Items[(++idx >= LocalizationList.Items.Count) ? LocalizationList.Items.Count - 1 : idx].Selected = true;
                LocalizationList.FocusedItem = LocalizationList.SelectedItems[0];
            }
            catch (System.ArgumentOutOfRangeException exc)
            {

            }
        }

        private void LocalListPrevItem()
        {
            int idx = 0;
            try
            {
                idx = LocalizationList.SelectedIndices[0];
            }
            catch (System.Exception exc)
            {
                idx = LocalizationList.Items.Count;
            }
            try
            {
                LocalizationList.Items[(--idx <= 0) ? 0 : idx].Selected = true;
                LocalizationList.FocusedItem = LocalizationList.SelectedItems[0];
            }
            catch (System.ArgumentOutOfRangeException exc)
            {

            }
        }

        private void ExitRoutine()
        {
            if (saved == false)
            {
                if (MessageBox.Show("Current file is unsaved.Want you save this file?", "Question", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    if (editedFile == "")
                    {
                        SaveAsLangTo();
                        return;

                    }
                    else
                    {
                        SaveLangTo(editedFile);
                        return;
                    }
                }
            }
        }

    }

    public class Entry
    {
        public object Key;
        public object Value;

        public Entry()
        {
        }

        public Entry(object key, object value)
        {
            Key = key;
            Value = value;
        }
    }
}
